// 布尔值
function booleanZone() {
  let isDone: boolean = false;
  return isDone
}

// 数字
function numberZone() {
  let decLiteral: number = 6;
  let hexLiteral: number = 0xf00d;
  let binaryLiteral: number = 0b1010;
  let octalLiteral: number = 0o744;
  return {
    decLiteral, hexLiteral, binaryLiteral, octalLiteral
  }
}

// 字符串
function stringZone() {
  let name: string = "blob";
  name = "smith";

  // 模板字符串
  let age: number = 18;
  let sentence: string = `Hello, my name is ${name}. I'll be ${age + 1} years old next month`;
  return sentence;
}

// 数组
function arrayZone() {
  // 方式一
  let list1st: number[] = [1, 2, 4]
  // 方式二
  let list2nd: Array<number> = [1, 23, 4]

  return {
    list1st,
    list2nd
  }
}

// 元组Tuple
function tupleZone() {
  let x: [string, number];
  // init
  x = ['abc', 123];
  // error
  // x = [123, 'abc']
}

// 枚举
function enumZone() {
  enum Color {
    Red = 1,
    Green,
    Blue
  }
  let r: Color = Color.Red
  let g: Color = Color.Green
  let b: Color = Color.Blue
  console.log(r, g, b)

  let colName: string = Color[2]
  console.log(colName)
}

// enumZone();

// any
function anyZone() {
  let notSure: any = 1;
  notSure = 'maybe a string instead';
  notSure = false;
}

// void
function voidZone(): void {
  console.log("This is my warning message")
}

// Null 和 Undefined    null 和 undefined是任何类型的子类型，当你指定了--strictNullChecks标记，null和undefined只能赋值给void和它们各自。
let u: undefined = undefined;
let n: null = null;

// never      never是任何类型的子类型，never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。
function error(msg: string): never {
  throw new Error(msg)
}

// 推断的返回值类型为never
function fail() {
  return error("Something is failed");
}

// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
  while (true) {
    // ...
  }
}

// Object  object 表示非原始类型
function create(o: object | null): void {

}

create({ prop: 0 })
create(null)
// create(42)
// create("string")
// create(true)
// create(undefined)

// 类型断言： 类型断言好比其它语言里的类型转换，但是不进行特殊的数据检查和解构。 它没有运行时的影响，只是在编译阶段起作用。

function assertions() {
  // 方式一 尖括号
  let someValue1st: any = "this is a string";
  let stringLength: number = (<string>someValue1st).length
  // 方式二 as
  let someValue2nd: any = "this is a string";
  let strLength: number = (someValue2nd as string).length
  // 两种形式等价。如果在TypeScript里使用JSX时，只有 as语法断言是被允许的。
}
